home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / GRAYPLOT / GRAYPLOT.C next >
C/C++ Source or Header  |  1990-07-11  |  5KB  |  202 lines

  1. /*
  2.  * Grayplot.c -- display a raw data file using a gray scale ramp palette,
  3.  * restoring the system palette on exit.  This program writes *directly* to the
  4.  * pixmap, so it is much much faster than using SetCPixel().
  5.  * 
  6.  * This program displays the contents of a raw data file.  The format it expects
  7.  * is a series of bytes, each of which represents a pixel.  An individual byte's
  8.  * value corresponds to a different shade of gray, ranging from black (for zero)
  9.  * to white (for 255).  For instance, if you have a 256 x 256 file, using any
  10.  * number of colors, it should be 65536 bytes long on disk.
  11.  * 
  12.  * Since this is example code, it contains a bare minimum of the standard error
  13.  * checks and user interface expected of a real program.  It is only intended as a
  14.  * starting point. 
  15.  * Copyright ⌐ 1990 Phil Shapiro, Symantec Corp.
  16.  */
  17. #include <EventMgr.h>
  18. #include <QuickDraw.h>
  19. #include <WindowMgr.h>
  20. #include <Color.h>
  21. #include <ColorToolBox.h>
  22. #include <StdFilePkg.h>
  23. #include <OSUtil.h>
  24.  
  25. #define ScreenDepth(gdh)    ((**((**gdh).gdPMap)).pixelSize)
  26.  
  27. /*
  28.  * Change these numbers to customize this program.
  29.  * COLORS    - the number of shades you want to use to display your data.  This is
  30.  *            usually the same as the number of shades the data was created with.
  31.  * WIDTH    - the width of the data in pixels (discrete data elements)
  32.  * HEIGHT    - the height of the data in pixels (discrete data elements)
  33.  * MAGNIFY    - magnification factor to apply to the display.  The actual
  34.  *            magnification is done by CopyBits().  This value can be a fraction.
  35.  * USE_GRAY    - if you don't want to use a gray scale palette, set this to zero
  36.  *            and the program will use the default system palette.
  37.  */
  38. #define COLORS    16
  39. #define WIDTH    256
  40. #define HEIGHT    256
  41. #define MAGNIFY    1.0
  42. #define USE_GRAY    1
  43.  
  44. unsigned char *Graph;    /* contents of file */
  45.  
  46. #define NIL 0L
  47. #define EXACT    0        /* used with pmTolerant, only exact matches */
  48.  
  49. void Init(void);
  50. void ReadFile(void);
  51. void SetGrayPalette(short depth, CWindowPtr w);
  52. void DrawWindow(Rect bounds);
  53. short log2(unsigned short);
  54. void RestoreClut(CTabHandle ctab, CWindowPtr w);
  55.  
  56. main()
  57. {
  58.     GDHandle    myGDevice;
  59.     Rect windRect, offBounds = { 0, 0, WIDTH, HEIGHT};
  60.     CWindowPtr    mainWindow;
  61.     CTabHandle    saveCTab;
  62.  
  63.     Init();
  64.     ReadFile();
  65.     myGDevice = GetGDevice();
  66.     saveCTab = (**((**myGDevice).gdPMap)).pmTable;
  67.     HandToHand(&saveCTab);
  68.  
  69.     SetRect(&windRect, 15, 15 + GetMBarHeight(),
  70.             (short)(MAGNIFY * WIDTH), (short)(MAGNIFY * HEIGHT));
  71.     mainWindow = (CWindowPtr)NewCWindow(NIL, &windRect, "\p", TRUE,
  72.                                         dBoxProc, (CWindowPtr)-1, TRUE, 0);
  73.     SetPort(mainWindow);
  74. #if USE_GRAY
  75.     SetGrayPalette(ScreenDepth(myGDevice), mainWindow);
  76. #endif
  77.     DrawWindow(offBounds);
  78.     while (!Button())
  79.         SystemTask();
  80. #if USE_GRAY
  81.     RestoreClut(saveCTab, mainWindow);
  82. #endif
  83.     DisposeWindow(mainWindow);
  84. }
  85.  
  86. #if USE_GRAY
  87. void RestoreClut(CTabHandle ctab, CWindowPtr w)
  88. {
  89.     PaletteHandle pal = NewPalette((**ctab).ctSize, ctab, pmTolerant, EXACT);
  90.  
  91.     SetPalette(w, pal, TRUE);
  92.     ActivatePalette(w);
  93. }
  94.  
  95. void SetGrayPalette(short depth, CWindowPtr w)
  96. {
  97.     short colors = 1 << depth;
  98.     CTabHandle ctab = GetCTable(depth);
  99.     PaletteHandle pal = NewPalette((**ctab).ctSize, NIL, pmTolerant, EXACT);
  100.     ColorSpec *specs;
  101.     short i;
  102.  
  103.     specs = (**ctab).ctTable;
  104.     for (i = 0; i < colors; ++i) {
  105.         specs[i].rgb.red = specs[i].rgb.green = specs[i].rgb.blue
  106.             = i * 65535 / (COLORS - 1);
  107.         specs[i].value = i;
  108.     }
  109.     /* this alerts the color mgr that the table changed */
  110.     (**ctab).ctSeed = GetCTSeed();
  111.     CTab2Palette(ctab, pal, pmTolerant, EXACT);
  112.     SetPalette(w, pal, TRUE);
  113.     ActivatePalette(w);
  114. }
  115. #endif        /* USE_GRAY */
  116.  
  117. void ReadFile()
  118. {
  119.     OSErr err;
  120.     SFReply reply;
  121.     short refNum;
  122.     long size = (long)sizeof(unsigned char) * WIDTH * HEIGHT;
  123.  
  124.     SFGetFile(0x00400030, "\p", NIL, -1, NIL, NIL, &reply);
  125.     if (reply.good) {
  126.         Graph = (unsigned char *) NewPtr(size);
  127.         if (Graph) {
  128.             if ((err = FSOpen(reply.fName, reply.vRefNum, &refNum)) == noErr) {
  129.                 err = FSRead(refNum, &size, Graph);
  130.                 err = FSClose(refNum);
  131.                 return;
  132.             }
  133.         }
  134.     }
  135.     ExitToShell();        /* User pressed cancel or file i/o messed up. */
  136. }
  137.  
  138. void DrawWindow(Rect bounds)
  139. {
  140.     short i;
  141.     PixMapHandle pm;
  142.     CTabHandle ctab;
  143.     ColorSpec *specs;
  144.  
  145. /*
  146.  * make pixmap from scratch, this should work in future versions...
  147.  */
  148.     pm = (PixMapHandle)NewHandleClear(sizeof(PixMap));
  149.     (**pm).baseAddr = (Ptr)Graph;
  150.     (**pm).rowBytes = (1L << 15) | WIDTH;    /* hi bit means it's a PixMap */
  151.     (**pm).bounds = bounds;
  152.     (**pm).hRes = 72;
  153.     (**pm).vRes = 72;
  154.     (**pm).pixelSize = 8;
  155.     (**pm).cmpCount = 1;
  156.     (**pm).cmpSize = 8;
  157. #if USE_GRAY
  158. /*
  159.  * munge a copy of the system color table for my offscreen world
  160.  */
  161.     ctab = GetCTable(log2(COLORS));
  162.     specs = (**ctab).ctTable;
  163.     for (i = 0; i < COLORS; ++i) {
  164.         specs[i].rgb.red = specs[i].rgb.green = specs[i].rgb.blue
  165.             = i * 65535 / (COLORS - 1);
  166.         specs[i].value = i;
  167.     }
  168.     /* this alerts the color mgr that the table changed */
  169.     (**ctab).ctSeed = GetCTSeed();
  170.     (**pm).pmTable = ctab;
  171. #else
  172.     (**pm).pmTable = (*((CGrafPtr)thePort)->portPixMap)->pmTable;
  173. #endif
  174.     HLock(pm);
  175.     CopyBits(*pm, &thePort->portBits, &(**pm).bounds, &thePort->portRect, srcCopy, 0);
  176.     HUnlock(pm);
  177. }
  178.  
  179. /*
  180.  * integer log base 2 function, to convert colors to bit depth
  181.  */
  182. short log2(unsigned short x)
  183. {
  184.     short t = 0;
  185.  
  186.     while (x >>= 1)
  187.         ++t;
  188.     return t;
  189. }
  190.  
  191. void Init()
  192. {
  193.     InitGraf(&thePort);
  194.     InitFonts();
  195.     FlushEvents( everyEvent, 0 );
  196.     InitWindows();
  197.     InitMenus();
  198.     TEInit();
  199.     InitDialogs(0L);
  200.     InitCursor();
  201. }
  202.